﻿using BCCommon;
using BCCommon.Enums;
using BCCommon.Extensions;
using BCData.MakeStaticPagingComponent.SystemServiceListing;
using BCData.MakeStaticPagingComponent.TemplateTag;
using BCData.MakeStaticPagingComponent.WebsiteTemplate;
using BCDto.MakeStaticPagingComponent.SystemServiceListing;
using BCEntity.MakeStaticPagingComponent.SystemServiceListing;
using BCEntity.MakeStaticPagingComponent.WebsiteTemplate;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using System.Text;

namespace BCService.MakeStaticPagingComponent.SystemServiceListingService
{
    /// <summary>
    /// 系统服务列表服务
    /// </summary>
    public class SystemServiceListingService : ISystemServiceListingService
    {
        private readonly IWebsiteTemplateData websiteTemplateData;
        private readonly ISystemServiceListingData systemServiceListingData;
        private readonly ITemplateTagData templateTagData;
        public SystemServiceListingService(IWebsiteTemplateData websiteTemplateData,
            ISystemServiceListingData systemServiceListingData,
            ITemplateTagData templateTagData)
        {
            this.websiteTemplateData = websiteTemplateData;
            this.systemServiceListingData = systemServiceListingData;
            this.templateTagData = templateTagData;
        }

        public SystemServiceListingDto Add(SystemServiceListingRequestDto systemServiceListingRequestDto)
        {
            if (systemServiceListingRequestDto.ResultType != StaticPageResultType.Value && systemServiceListingRequestDto.ResultType != StaticPageResultType.NULL)
            {
                if (string.IsNullOrEmpty(systemServiceListingRequestDto.ResultEntityName))
                {
                    throw new ArgumentException("返回对象名称不能为空。");
                }
            }
            if (this.systemServiceListingData.CheckSystemServiceListingExists(systemServiceListingRequestDto.WebsiteTemplateId, systemServiceListingRequestDto.DisplayName))
            {
                throw new ArgumentException("服务展示名称已存在。");
            }
            WebsiteTemplateEntity websiteTemplateEntity = this.websiteTemplateData.GetUsed();
            if (websiteTemplateEntity == null)
            {
                throw new ArgumentException("未使用任何网站模板，请先选择使用某个网站模板。");
            }
            SystemServiceListingEntity systemServiceListingEntity = systemServiceListingRequestDto.As<SystemServiceListingEntity>();
            systemServiceListingEntity.WebsiteTemplateId = websiteTemplateEntity.WebsiteTemplateId;
            return this.systemServiceListingData.Add(systemServiceListingEntity).As<SystemServiceListingDto>();
        }

        public void Delete(int systemServiceListingId)
        {
            SystemServiceListingEntity entity = this.systemServiceListingData.Get(systemServiceListingId);
            if (entity != null && entity.IsSystem)
            {
                throw new ArgumentException("此服务为系统默认服务，无法删除。");
            }
            this.systemServiceListingData.Delete(systemServiceListingId);
        }

        public SystemServiceListingDto Get(int systemServiceListingId)
        {
            return this.systemServiceListingData.Get(systemServiceListingId).As<SystemServiceListingDto>();
        }

        public IEnumerable<SystemServiceListingDto> Query(int websiteTemplateId)
        {
            return this.systemServiceListingData.Query(websiteTemplateId).As<IEnumerable<SystemServiceListingDto>>();
        }

        public PageableList<SystemServiceListingDto> Query(int websiteTemplateId, string displayName, bool? ascending, int index = 1, int size = 20)
        {
            var list = this.systemServiceListingData.Query(websiteTemplateId, displayName, out int dataCount, ascending, index, size);

            return new PageableList<SystemServiceListingDto>
            {
                Count = dataCount,
                Items = list.As<IEnumerable<SystemServiceListingDto>>()
            };
        }

        public IDictionary<string, string> GetSystemServiceResultTags(int systemServiceListingId)
        {
            SystemServiceListingEntity entity = this.systemServiceListingData.Get(systemServiceListingId);
            if (entity == null)
            {
                throw new ArgumentException("此系统服务信息不正确。");
            }
            IDictionary<string, string> dictionary = new Dictionary<string, string>();
            if (entity.ResultType.In(StaticPageResultType.Array, StaticPageResultType.Object, StaticPageResultType.PageableList))
            {
                Type type = Type.GetType(entity.ResultEntityName);
                if (type == null)
                    throw new ArgumentException("此对象模型名称错误");

                object obj = Activator.CreateInstance(type, true);

                PropertyInfo[] properties = obj.GetType().GetProperties();

                foreach (PropertyInfo property in properties)
                {
                    Attribute attribute = property.GetCustomAttribute(typeof(DisplayAttribute));
                    string parentDisplayName = string.Empty;
                    string parentPropertyName = string.Empty;
                    if (attribute != null){
                        DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                        parentDisplayName = displayAttribute.Name;
                        parentPropertyName = property.Name;
                        dictionary.Add(property.Name, displayAttribute.Name);
                    }
                    if (property.PropertyType.IsGenericType)
                    {
                        if (!property.PropertyType.IsValueType)
                        {
                            GetChildrenProperty(property, parentPropertyName, parentDisplayName, dictionary);
                        }
                    }

                }
            }
            return dictionary;
        }
        private void GetChildrenProperty(PropertyInfo property,string propertyName,string displayName,IDictionary<string,string> dictionary)
        {
            if(property.PropertyType.GenericTypeArguments.Length==0)
            {
                return;
            }
            Type type = Type.GetType(property.PropertyType.GenericTypeArguments[0].FullName + "," + property.GetMethod.DeclaringType.Assembly.GetName().Name);
            if (type == null)
                throw new ArgumentException("此对象模型名称错误");
            object obj = Activator.CreateInstance(type, true);

            PropertyInfo[] properties = obj.GetType().GetProperties();
            foreach (PropertyInfo propertyInfo in properties)
            {
                Attribute attribute = propertyInfo.GetCustomAttribute(typeof(DisplayAttribute));
                string parentDisplayName = displayName;
                string parentPropertyName = propertyName;
                if (attribute != null)
                {
                    DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                    parentDisplayName = displayAttribute.Name;
                    parentPropertyName = propertyInfo.Name;
                    if (!dictionary.ContainsKey(propertyName + "." + propertyInfo.Name))
                    {
                        dictionary.Add(propertyName+"."+propertyInfo.Name, displayName + "." + displayAttribute.Name);
                    }
                }
                if (propertyInfo.PropertyType.IsGenericType)
                {
                    GetChildrenProperty(propertyInfo, parentPropertyName, parentDisplayName, dictionary);
                }
            }
        }
        public SystemServiceListingDto Update(int systemServiceListingId, SystemServiceListingRequestDto systemServiceListingRequestDto)
        {
            SystemServiceListingEntity entity = this.systemServiceListingData.Get(systemServiceListingId);
            if (entity == null)
            {
                throw new ArgumentException("此系统服务信息不正确。");
            }
            if (!entity.DisplayName.Equals(systemServiceListingRequestDto.DisplayName))
            {
                if (this.systemServiceListingData.CheckSystemServiceListingExists(entity.WebsiteTemplateId, systemServiceListingRequestDto.DisplayName))
                {
                    throw new ArgumentException("此服务展示名称已存在。");
                }
            }

            SystemServiceListingEntity systemServiceListingEntity = systemServiceListingRequestDto.As<SystemServiceListingEntity>();
            systemServiceListingEntity.SystemServiceListingId = systemServiceListingId;

            return this.systemServiceListingData.Update(systemServiceListingEntity).As<SystemServiceListingDto>();
        }
    }
}
